package org.sqp.wechat.client;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * @author sunqipeng
 * @date 2019/1/7
 */
public class WechatWebClient {
    private String wr_skey;
    private String wr_vid;
    private String wr_name;
    private String wr_avatar;
    private String wr_logined;
    private SimpleCookieJar cookieJar;
    private OkHttpClient httpClient;
    private Map<Integer,String> bookIdNameMap;

    public WechatWebClient(String wr_skey, String wr_vid) {
        this(wr_skey, wr_vid, "%E5%AD%99%E5%85%B6%E9%B9%8F", "http%3A%2F%2Fthirdwx.qlogo.cn%2Fmmopen%2Fvi_32%2FajNVdqHZLLArBAYxQRwU12REGyLfpz94MxNG9WRQSialeGNSXL11PXicdNLy82pnOvib6oiaNuj7D3TblDI0j2YZkQ%2F132", "1");
    }

    public WechatWebClient(String wr_skey, String wr_vid, String wr_name, String wr_avatar, String wr_logined) {
        this.wr_skey = wr_skey;
        this.wr_vid = wr_vid;
        this.wr_name = wr_name;
        this.wr_avatar = wr_avatar;
        this.wr_logined = wr_logined;
        cookieJar = new SimpleCookieJar();
        String domain = "weread.qq.com";
        cookieJar.add(new Cookie.Builder().name("wr_vid").value(this.wr_vid).domain(domain).build());
        cookieJar.add(new Cookie.Builder().name("wr_skey").value(this.wr_skey).domain(domain).build());
        cookieJar.add(new Cookie.Builder().name("wr_name").value(this.wr_name).domain(domain).build());
        cookieJar.add(new Cookie.Builder().name("wr_logined").value(this.wr_logined).domain(domain).build());
        cookieJar.add(new Cookie.Builder().name("wr_avatar").value(this.wr_avatar).domain(domain).build());
        httpClient = new OkHttpClient.Builder().cookieJar(cookieJar).build();
        bookIdNameMap = new HashMap<Integer, String>();
    }

    private Request.Builder baseReqBuilder() {
        return new Request.Builder()
                .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 MicroMessenger/6.5.2.501 NetType/WIFI WindowsWechat QBCore/3.43.691.400 QQBrowser/9.0.2524.400")
//                .addHeader("Accept-Encoding", "gzip, deflate")
                .addHeader("Accept-Language", "zh-CN,zh;q=0.8,en-us;q=0.6,en;q=0.5;q=0.4")
                .addHeader("Accept", "*/*")
                .addHeader("Host", "weread.qq.com")
                .addHeader("Referer", "https://weread.qq.com/wrpage/wechat/search/read/462952/4?ref=mp")
                .addHeader("Connection", "keep-alive")
                .addHeader("Content-Type", "application/x-www-form-urlencoded");
    }


    private String unZipStream(InputStream in) {
//        try (GZIPInputStream gzs = new GZIPInputStream(in)){
        try {
            return IOUtils.toString(in, "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
//        }catch (Exception e){
//            e.printStackTrace();
//        }
        return null;
    }

    private Response execute(Request request) throws Exception {
        return httpClient.newCall(request).execute();
    }


    public List<String> search(String keyword) {
        List<String> books = new ArrayList<String>();
        try {
            FormBody formBody = new FormBody.Builder().add("keyword", keyword).build();
            Response response = execute(baseReqBuilder().url("https://weread.qq.com/wrpage/wechat/search/store/search/more")
                    .post(formBody).build());
            String resp = unZipStream(response.body().byteStream());

            if (resp != null) {
                JSONArray jsonArray = JSON.parseObject(resp).getJSONObject("data").getJSONArray("books");
                for (Object object : jsonArray) {
                    JSONObject obj = (JSONObject) object;
                    JSONObject bookInfo = obj.getJSONObject("bookInfo");
                    String title = bookInfo.getString("title");
                    String author = bookInfo.getString("author");
                    Integer bookId = bookInfo.getInteger("bookId");
                    bookIdNameMap.put(bookId, title);
                    System.out.println(String.format("%d 《%s》- %s", bookId, title, author));
                }
            }
        } catch (Exception e) {

        }

        return books;
    }

    public void download(int bookId) {
        String name = bookIdNameMap.get(bookId);
        if (name == null){
            System.out.println("未找到对应图书");
            return;
        }

        int num = 1;
        Integer nextUid = 1;

        System.out.println("下载 "+name);
        String dirPath = "D:/tmp/微信读书/"+name;
        File file = new File(dirPath);
        if (!file.exists()) {
            try {
                file.mkdirs();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            File[] files = file.listFiles();
            if (files!=null && files.length>0){
                Map<Integer,Integer> map = new HashMap<Integer, Integer>();
                for (File f:files){
                    System.out.println(f.getName());
                    String[] strings = f.getName().split("-");
                    map.put(Integer.parseInt(strings[0]),Integer.parseInt(strings[1]));
                }
                ArrayList<Integer> list = new ArrayList<Integer>(map.keySet());
                Collections.sort(list);
                num = list.get(list.size()-1);
                nextUid = map.get(num);
                System.out.println("从"+num+"开始断点续传");
            }
        }

        for (;;){
            if (nextUid == null) {
                break;
            }
            nextUid = requestChapter(num++, nextUid, bookId, dirPath);
        }
        System.out.println("done!");
    }

    public Integer requestChapter(int num, int uid, int bookId, String dirPath) {
        Integer nextUid = null;
        try {
            if (num % 100 == 0) {
                System.gc();
                System.out.println("休息3秒 防封");
                Thread.sleep(3000);
            }
            Response response = execute(baseReqBuilder().url("https://weread.qq.com/wrpage/wechat/search/read/chapter?uid=" + uid + "&bookId=" + bookId).build());
            String contentType = response.header("Content-Type");
//            System.out.println(contentType);
            if (contentType != null && contentType.indexOf("json") > 0) {
                String resp = unZipStream(response.body().byteStream());
                if (resp == null){
                    requestChapter(num, ++uid, bookId, dirPath);
                }
                JSONObject data = JSON.parseObject(resp).getJSONObject("data");
                if (data == null){
                    if (resp != null && resp.contains("登录超时")){
                        System.out.println("登陆超时 系统推出");
                        System.exit(0);
                    }
                    System.out.println(resp);
                }
                String title = data.getString("title");
                String content = data.getString("content");
                nextUid = data.getInteger("nextUid");
                title = formatChapterName(title);
                System.out.println("正在下载 "+title+"...");
                File o = new File(dirPath + File.separator + num + "-"+uid+"-" + title + ".html");
                IOUtils.write(content, new FileOutputStream(o), "utf-8");
            } else {
                System.out.println(contentType + " is not json format");
                System.out.println(response.body().toString());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return nextUid;
    }


    private String formatChapterName(String title){
        title = title.replace("\\","-");
        title = title.replace("/","-");
        return title;
    }

    private void html2Pdf(String dir){
        //TODO
    }
}
